package galaxy

import (
	"context"

	"gddgame.cc/galaxy/server/composer"
	"gddgame.cc/galaxy/server/ska"
	"gddgame.cc/galaxy/server/web"
	"gddgame.cc/galaxy/utils/def"
)

type Context struct {
	def.Logger
	def.Store
	def.ID
}

var (
	webProvide      = &webServer{}
	skaProvide      = &skaServer{}
	composerProvide = &composerServer{}
	serverContainer = []ServerProvider{
		{"web", nil, webProvide, webProvide.OnCreate, webProvide.OnStart, nil},
		{"ska", nil, skaProvide, skaProvide.OnCreate, nil, nil},
		{"composer", nil, composerProvide, composerProvide.OnCreate, composerProvide.OnStart, composerProvide.OnStop},
	}
)

type webServer struct {
	Web    web.Engine `galaxy:"inject"`
	Logger *Logger    `inject:""`
}

func (server *webServer) OnCreate() error {
	web := web.NewEngine()
	web.SetLogger(server.Logger.LoggerWrap("Server", "web"))
	web.SetDebug(flags.Debug)

	server.Web = web
	return nil
}

func (server *webServer) OnStart(ctx context.Context) error {
	return server.Web.Listen()
}

func (server *webServer) OnStop() error {
	return server.Web.Close()
}

type skaServer struct {
	Ska    ska.Engine `galaxy:"inject"`
	Logger *Logger    `inject:""`
}

func (server *skaServer) OnCreate() error {
	ska := ska.NewEngine(rl.logger)
	ska.SetDebug(flags.Debug)

	server.Ska = ska
	return nil
}

type composerServer struct {
	Composer composer.Composer `galaxy:"inject"`

	composer.BasisCloser `inject:""`

	Logger *Logger `inject:""`
}

func (server *composerServer) OnCreate() error {
	cp := composer.NewCompose(server.Logger)
	cp.SetDebug(flags.Debug)
	cp.SetBasis(server.BasisCloser)

	server.Composer = cp
	return nil
}

func (server *composerServer) OnStart(ctx context.Context) error {
	return server.Composer.Start(ctx)
}

func (server *composerServer) OnStop() error {
	return server.Composer.Stop()
}

func registerCoreServer() error {
	for _, instance := range serverContainer {
		if err := RegisterServer(instance); err != nil {
			return err
		}
	}
	return nil
}
